Fix bug #321560, based on a patch by Bogdan Nicula (bogdanni@hotmail.com):
authorFederico Mena Quintero <federico@ximian.com>
Mon, 28 Nov 2005 22:25:03 +0000 (22:25 +0000)
committerFederico Mena Quintero <federico@src.gnome.org>
Mon, 28 Nov 2005 22:25:03 +0000 (22:25 +0000)
2005-11-28  Federico Mena Quintero  <federico@ximian.com>

Fix bug #321560, based on a patch by Bogdan Nicula (bogdanni@hotmail.com):

* gtk/gtkfilechooserdefault.c (up_folder_handler): Don't add the
current_folder to the pending select paths here; the path bar will
give it to us now.
(path_bar_clicked): Add the child_path to the pending select paths
here.
(show_and_select_paths): Don't filter out folders.
(show_and_select_paths): Don't take separate arguments for
only_one_path and multiple paths.

* tests/autotestfilechooser.c (test_folder_switch_and_filters):
New test about preserving the filters when we change folders.

ChangeLog
ChangeLog.pre-2-10
gtk/gtkfilechooserdefault.c
tests/autotestfilechooser.c
tests/file-chooser-test-dir/empty [new file with mode: 0644]
tests/file-chooser-test-dir/text.txt [new file with mode: 0644]

index e59ec56a6fbe712d3a82a306ce45a69b766d326b..876bb3f96511093612afc2ff965f600ffc4e08e4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2005-11-28  Federico Mena Quintero  <federico@ximian.com>
+
+       Fix bug #321560, based on a patch by Bogdan Nicula (bogdanni@hotmail.com):
+
+       * gtk/gtkfilechooserdefault.c (up_folder_handler): Don't add the
+       current_folder to the pending select paths here; the path bar will
+       give it to us now.
+       (path_bar_clicked): Add the child_path to the pending select paths
+       here.
+       (show_and_select_paths): Don't filter out folders.
+       (show_and_select_paths): Don't take separate arguments for
+       only_one_path and multiple paths.
+
+       * tests/autotestfilechooser.c (test_folder_switch_and_filters):
+       New test about preserving the filters when we change folders.
+
 2005-11-28  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkscale.c (_gtk_scale_format_value): Insert an LRM, to prevent
index e59ec56a6fbe712d3a82a306ce45a69b766d326b..876bb3f96511093612afc2ff965f600ffc4e08e4 100644 (file)
@@ -1,3 +1,19 @@
+2005-11-28  Federico Mena Quintero  <federico@ximian.com>
+
+       Fix bug #321560, based on a patch by Bogdan Nicula (bogdanni@hotmail.com):
+
+       * gtk/gtkfilechooserdefault.c (up_folder_handler): Don't add the
+       current_folder to the pending select paths here; the path bar will
+       give it to us now.
+       (path_bar_clicked): Add the child_path to the pending select paths
+       here.
+       (show_and_select_paths): Don't filter out folders.
+       (show_and_select_paths): Don't take separate arguments for
+       only_one_path and multiple paths.
+
+       * tests/autotestfilechooser.c (test_folder_switch_and_filters):
+       New test about preserving the filters when we change folders.
+
 2005-11-28  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkscale.c (_gtk_scale_format_value): Insert an LRM, to prevent
index d25d45897790bf4dcd5ae85c2791f5f7384af7ad..ebf4ddc0cd4ebfa6543be35e163eba9a25b49a24 100644 (file)
@@ -5044,105 +5044,70 @@ browse_files_center_selected_row (GtkFileChooserDefault *impl)
 static gboolean
 show_and_select_paths (GtkFileChooserDefault *impl,
                       const GtkFilePath     *parent_path,
-                      const GtkFilePath     *only_one_path,
                       GSList                *paths,
-                      GError               **error)
+                      GError                **error)
 {
   GtkFileFolder *folder;
-  gboolean success;
   gboolean have_hidden;
   gboolean have_filtered;
+  GSList *l;
 
   profile_start ("start", NULL);
 
-  if (!only_one_path && !paths)
+  if (!paths)
     {
       profile_end ("end", NULL);
       return TRUE;
     }
 
-  folder = gtk_file_system_get_folder (impl->file_system, parent_path, GTK_FILE_INFO_IS_HIDDEN, error);
+  folder = gtk_file_system_get_folder (impl->file_system, parent_path, GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_IS_HIDDEN, error);
   if (!folder)
     {
       profile_end ("end", NULL);
       return FALSE;
     }
 
-  success = FALSE;
   have_hidden = FALSE;
   have_filtered = FALSE;
 
-  if (only_one_path)
+  for (l = paths; l; l = l->next)
     {
+      const GtkFilePath *path;
       GtkFileInfo *info;
 
-      info = gtk_file_folder_get_info (folder, only_one_path, error);
-      if (info)
-       {
-         success = TRUE;
-         have_hidden = gtk_file_info_get_is_hidden (info);
-         have_filtered = get_is_file_filtered (impl, only_one_path, info);
-         gtk_file_info_free (info);
-       }
-    }
-  else
-    {
-      GSList *l;
+      path = l->data;
 
-      for (l = paths; l; l = l->next)
+      /* NULL GError */
+      info = gtk_file_folder_get_info (folder, path, NULL);
+      if (info)
        {
-         const GtkFilePath *path;
-         GtkFileInfo *info;
+         if (!have_hidden)
+           have_hidden = gtk_file_info_get_is_hidden (info);
 
-         path = l->data;
+         if (!have_filtered)
+           have_filtered = !gtk_file_info_get_is_folder (info) && get_is_file_filtered (impl, path, info);
 
-         /* NULL GError */
-         info = gtk_file_folder_get_info (folder, path, NULL);
-         if (info)
-           {
-             if (!have_hidden)
-               have_hidden = gtk_file_info_get_is_hidden (info);
-
-             if (!have_filtered)
-               have_filtered = get_is_file_filtered (impl, path, info);
-
-             gtk_file_info_free (info);
+         gtk_file_info_free (info);
 
-             if (have_hidden && have_filtered)
-               break; /* we now have all the information we need */
-           }
+         if (have_hidden && have_filtered)
+           break; /* we now have all the information we need */
        }
-
-      success = TRUE;
     }
 
   g_object_unref (folder);
 
-  if (!success)
-    {
-      profile_end ("end", NULL);
-      return FALSE;
-    }
-
   if (have_hidden)
     g_object_set (impl, "show-hidden", TRUE, NULL);
 
   if (have_filtered)
     set_current_filter (impl, NULL);
 
-  if (only_one_path)
-    _gtk_file_system_model_path_do (impl->browse_files_model, only_one_path, select_func, impl);
-  else
+  for (l = paths; l; l = l->next)
     {
-      GSList *l;
-
-      for (l = paths; l; l = l->next)
-       {
-         const GtkFilePath *path;
+      const GtkFilePath *path;
 
-         path = l->data;
-         _gtk_file_system_model_path_do (impl->browse_files_model, path, select_func, impl);
-       }
+      path = l->data;
+      _gtk_file_system_model_path_do (impl->browse_files_model, path, select_func, impl);
     }
 
   profile_end ("end", NULL);
@@ -5160,7 +5125,7 @@ pending_select_paths_process (GtkFileChooserDefault *impl)
   if (impl->pending_select_paths)
     {
       /* NULL GError */
-      show_and_select_paths (impl, impl->current_folder, NULL, impl->pending_select_paths, NULL);
+      show_and_select_paths (impl, impl->current_folder, impl->pending_select_paths, NULL);
       pending_select_paths_free (impl);
       browse_files_center_selected_row (impl);
     }
@@ -5492,8 +5457,12 @@ gtk_file_chooser_default_select_path (GtkFileChooser    *chooser,
   if (same_path && impl->load_state == LOAD_FINISHED)
     {
       gboolean result;
+      GSList paths;
+
+      paths.data = (gpointer) path;
+      paths.next = NULL;
 
-      result = show_and_select_paths (impl, parent_path, path, NULL, error);
+      result = show_and_select_paths (impl, parent_path, &paths, error);
       gtk_file_path_free (parent_path);
       return result;
     }
@@ -6913,6 +6882,9 @@ path_bar_clicked (GtkPathBar            *path_bar,
                  gboolean               child_is_hidden,
                  GtkFileChooserDefault *impl)
 {
+  if (child_path)
+    pending_select_paths_add (impl, child_path);
+
   if (!change_folder_and_display_error (impl, file_path))
     return;
 
@@ -6922,18 +6894,6 @@ path_bar_clicked (GtkPathBar            *path_bar,
    */
   if (child_is_hidden)
     g_object_set (impl, "show-hidden", TRUE, NULL);
-
-  /* Say we have "/foo/bar/baz" and the user clicks on "bar". We should then
-   * focus the "baz" entry in the files list - the reason for this is that
-   * if user furst changed to /foo/bar/baz from /foo/bar unintentionally 
-   * instead of /foo/bar/baz1, it will take quite some time to scroll to baz1 
-   * in the file list, especially if this directory contains lots of folders
-   */
-  if (child_path != NULL)
-    {
-      gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (impl), child_path, NULL);
-      browse_files_center_selected_row (impl);
-    }
 }
 
 static const GtkFileInfo *
@@ -7407,7 +7367,6 @@ location_popup_handler (GtkFileChooserDefault *impl,
 static void
 up_folder_handler (GtkFileChooserDefault *impl)
 {
-  pending_select_paths_add (impl, impl->current_folder);
   _gtk_path_bar_up (GTK_PATH_BAR (impl->browse_path_bar));
 }
 
index 78de74a2ebe44c765180549be01db220d4e5f411..d169042efdca75e849a4d520e1faa00b0046797b 100644 (file)
@@ -568,6 +568,106 @@ test_button_folder_states (void)
   return passed;
 }
 
+static gboolean
+sleep_timeout_cb (gpointer data)
+{
+  gtk_main_quit ();
+  return FALSE;
+}
+
+static void
+sleep_in_main_loop (int milliseconds)
+{
+  g_timeout_add (milliseconds, sleep_timeout_cb, NULL);
+  gtk_main ();
+}
+
+static gboolean
+test_folder_switch_and_filters (void)
+{
+  gboolean passed;
+  char *cwd;
+  char *base_dir;
+  GtkFilePath *cwd_path;
+  GtkFilePath *base_dir_path;
+  GtkWidget *dialog;
+  GtkFileFilter *all_filter;
+  GtkFileFilter *txt_filter;
+  GtkFileChooserDefault *impl;
+
+  passed = TRUE;
+
+  cwd = g_get_current_dir ();
+  base_dir = g_build_filename (cwd, "file-chooser-test-dir", NULL);
+
+  dialog = gtk_file_chooser_dialog_new ("Test", NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
+                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                                       NULL);
+  impl = get_impl_from_dialog (dialog);
+
+  cwd_path = gtk_file_system_filename_to_path (impl->file_system, cwd);
+  base_dir_path = gtk_file_system_filename_to_path (impl->file_system, base_dir);
+
+  passed = passed && gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
+  if (!passed)
+    goto out;
+
+  /* All files filter */
+
+  all_filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (all_filter, "All files");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all_filter);
+
+  /* *.txt filter */
+
+  txt_filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (all_filter, "*.txt");
+  gtk_file_filter_add_pattern (txt_filter, "*.txt");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), txt_filter);
+
+  /* Test filter set */
+
+  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), all_filter);
+  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == all_filter);
+
+  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), txt_filter);
+  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
+
+  log_test (passed, "test_folder_switch_and_filters(): set and get filter");
+
+  gtk_widget_show (dialog);
+
+  /* Test that filter is unchanged when we switch folders */
+
+  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd);
+  sleep_in_main_loop (1000);
+  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
+
+  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
+  sleep_in_main_loop (500);
+
+  g_signal_emit_by_name (impl->browse_path_bar, "path-clicked",
+                        (GtkFilePath *) cwd_path,
+                        (GtkFilePath *) base_dir_path,
+                        FALSE);
+  sleep_in_main_loop (500);
+  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
+
+  log_test (passed, "test_folder_switch_and_filters(): filter after changing folder");
+
+ out:
+  g_free (cwd);
+  g_free (base_dir);
+  gtk_file_path_free (cwd_path);
+  gtk_file_path_free (base_dir_path);
+
+  gtk_widget_destroy (dialog);
+
+  log_test (passed, "test_folder_switch_and_filters(): all filter tests");
+  return passed;
+}
+
 static GLogFunc default_log_handler;
 static int num_warnings;
 static int num_errors;
@@ -605,10 +705,10 @@ main (int argc, char **argv)
   gtk_init (&argc, &argv);
 
   /* Start tests */
-
   passed = passed && test_action_widgets ();
   passed = passed && test_reload ();
   passed = passed && test_button_folder_states ();
+  passed = passed && test_folder_switch_and_filters ();
   log_test (passed, "main(): main tests");
 
   /* Warnings and errors */
diff --git a/tests/file-chooser-test-dir/empty b/tests/file-chooser-test-dir/empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/file-chooser-test-dir/text.txt b/tests/file-chooser-test-dir/text.txt
new file mode 100644 (file)
index 0000000..cd08755
--- /dev/null
@@ -0,0 +1 @@
+Hello world!